package com.lbb.sqlsession;

import com.lbb.pojo.Configuration;
import com.lbb.pojo.MappedStatement;


import java.lang.Exception;
import java.lang.reflect.*;
import java.sql.SQLException;
import java.util.List;

public class DefaultSqlSession implements SqlSession{
    private Configuration configuration;

    public DefaultSqlSession(Configuration configuration) {
        this.configuration = configuration;
    }

    @Override
    public <E> List<E> selectList(String statementid, Object... params) throws Exception {
        SimpleExecutor simpleExecutor = new SimpleExecutor();
        MappedStatement mappedStatement = configuration.getMappedStatementHashMap().get(statementid);
        List<E> list = simpleExecutor.query(configuration,mappedStatement,params);
        return (List<E>) list;
    }

    @Override
    public <T> T selectOne(String statementid, Object... params) throws Exception {
        List<T> list = selectList(statementid,params);
        if(list.size() == 1){
            return (T)list.get(0);
        }else{
            throw new RuntimeException("查询结果过多");
        }
    }

    @Override
    public int update(String statementid, Object... params) throws Exception {
        SimpleExecutor simpleExecutor = new SimpleExecutor();
        MappedStatement mappedStatement = configuration.getMappedStatementHashMap().get(statementid);
        int result = simpleExecutor.update(configuration,mappedStatement,params);
        return result;
    }

    @Override
    public int delete(String statementid, Object... params) throws Exception {
        SimpleExecutor simpleExecutor = new SimpleExecutor();
        MappedStatement mappedStatement = configuration.getMappedStatementHashMap().get(statementid);
        int result = simpleExecutor.update(configuration,mappedStatement,params);
        return result;
    }

    @Override
    public int insert(String statementid, Object... params) throws Exception {
        SimpleExecutor simpleExecutor = new SimpleExecutor();
        MappedStatement mappedStatement = configuration.getMappedStatementHashMap().get(statementid);
        int result = simpleExecutor.update(configuration,mappedStatement,params);
        return result;
    }

    @Override
    public <T> T getMapper(Class<?> mapperClass){
       Object proxyInstance = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(),
               new Class[]{mapperClass}, new InvocationHandler() {
                   @Override
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                       String methodName = method.getName();
                       String className = method.getDeclaringClass().getName();
                       String statementid = className + "." + methodName;

                       if(methodName.contains("select")){
                           Type genericReturnType = method.getGenericReturnType();
                           if(genericReturnType instanceof ParameterizedType){
                               List<Object> list = selectList(statementid,args);
                               return list;
                           }else{
                               return selectOne(statementid,args);
                           }
                       }else if(methodName.contains("update")){
                           return (Object)update(statementid,args);
                       }else if(methodName.contains("delete")){
                           return (Object)delete(statementid,args);
                       }else if(methodName.contains("insert")){
                           return (Object)insert(statementid,args);
                       }else{
                           throw new RuntimeException("无匹配的函数");
                       }
                   }
               });
            return (T) proxyInstance;
    }

}
